package chen.web.util.velocity;

import java.util.Iterator;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;

import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.RuntimeServices;
import org.apache.velocity.runtime.resource.Resource;
import org.apache.velocity.runtime.resource.ResourceCache;

import chen.web.cache.CacheUtils;

/**
 * 使用ehcache缓存velocity资源，当清空缓存中的资源后，velocity会重新加载。
 * 用于修改模板后，即时更新模板
 * 支持在velocity配置文件中设置缓存大小，默认值是89。相关属性名：resource.manager.defaultcache.size
 * @author chen
 *
 */
public class MyResourceCache implements ResourceCache{

	private Cache VolocityResourceCache = null;
	/**
	 * 默认缓存大小，可在velocity配置中设置resource.manager.defaultcache.size代替默认值
	 */
	private static final int DefaultMaxElementSize = 89;
	private static final String VolocityResourceCacheName = "volocity-resource-cache";
	
	@Override
	public Iterator enumerateKeys() {
		// TODO Auto-generated method stub
		return VolocityResourceCache.getKeys().iterator();
	}

	@Override
	public Resource get(Object key) {
		// TODO Auto-generated method stub
		Element elem = VolocityResourceCache.get(key);
		if(elem != null){
			return (Resource)elem.getObjectValue();
		}
		return null;
	}

	@Override
	public void initialize(RuntimeServices rs) {
		// TODO Auto-generated method stub
        int maxSize = rs.getInt(RuntimeConstants.RESOURCE_MANAGER_DEFAULTCACHE_SIZE, DefaultMaxElementSize);
		CacheConfiguration config = new CacheConfiguration(VolocityResourceCacheName, Integer.MAX_VALUE)
			.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU)
			.maxElementsInMemory(maxSize)
			.eternal(true)
			.diskPersistent(false);
		VolocityResourceCache = new Cache(config);
		CacheManager.create().addCache(VolocityResourceCache);
		CacheUtils.storeDescription(VolocityResourceCache, "缓存velocity模板");
	}

	@Override
	public Resource put(Object key, Resource value) {
		// TODO Auto-generated method stub
		Resource resource = get(key);
		VolocityResourceCache.put(new Element(key, value));
		return resource;
	}

	@Override
	public Resource remove(Object key) {
		// TODO Auto-generated method stub
		Resource resource = get(key);
		if(VolocityResourceCache.remove(key)){
			return resource;
		}
		return null;
	}

}
